

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/favicon.ico">
  <link rel="icon" href="/img/favicon.ico">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="叶尘的技术升级小木屋">
  <meta name="author" content="叶尘">
  <meta name="keywords" content="">
  
  <title>1.项目介绍及基础环境搭建 - 叶尘的技术升级小木屋</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10.7.2/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
  



<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->

  
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/shubiao.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/gundongtiao.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/daziyanse.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/toubudaziji.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css">



  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"www.yechen-blog.cn","root":"/","version":"1.8.11","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null}},"search_path":"/local-search.xml"};
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.4.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/">&nbsp;<strong>YECHEN</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-qrcode"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/playlist/">
                <i class="iconfont icon-music"></i>
                音乐
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" target="_self" role="button"
                 data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <i class="iconfont icon-books"></i>
                链接
              </a>
              <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/">
                    
                    主题博客
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/docs/guide/">
                    
                    配置指南
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/docs/icon/">
                    
                    图标用法
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://www.bilibili.com">
                    
                    哔哩哔哩
                  </a>
                
              </div>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/img/banner.jpg') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="1.项目介绍及基础环境搭建">
              
            </span>

            
              <div class="mt-3">
  
    <span class="post-meta mr-2">
      <i class="iconfont icon-author" aria-hidden="true"></i>
      叶尘
    </span>
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2021-09-25 14:31" pubdate>
        星期六, 九月 25日 2021, 2:31 下午
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      5.7k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      75
       分钟
    </span>
  

  
  
    
      <!-- LeanCloud 统计文章PV -->
      <span id="leancloud-page-views-container" class="post-meta" style="display: none">
        <i class="iconfont icon-eye" aria-hidden="true"></i>
        <span id="leancloud-page-views"></span> 次
      </span>
    
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">1.项目介绍及基础环境搭建</h1>
            
            <div class="markdown-body">
              <h1 id="一、项目简介"><a href="#一、项目简介" class="headerlink" title="一、项目简介"></a>一、项目简介</h1><p>项目<a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1np4y1C7Yf">学习地址</a></p>
<blockquote>
<p>谷粒商城是一个 B2C 模式的电商平台，销售自营商品给客户。</p>
</blockquote>
<p><strong>项目技术&amp;特色</strong>：</p>
<ul>
<li>前后分离开发，并开发基于 vue 的后台管理系统 </li>
<li>SpringCloud 全新的解决方案 </li>
<li>应用监控、限流、网关、熔断降级等分布式方案 全方位涉及</li>
<li>透彻讲解分布式事务、分布式锁等分布式系统的难点</li>
<li>分析高并发场景的编码方式，线程池，异步编排等使用</li>
<li>压力测试与性能优化</li>
<li>各种集群技术的区别以及使用</li>
<li>CI/CD 使用</li>
<li>……</li>
</ul>
<p><strong>项目的微服务架构图</strong>：</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.7vvyl2pcx0o.png" srcset="/img/loading.gif" lazyload alt="项目的微服务架构图"></p>
<p>前后分离开发，分为内网部署和外网部署，外网是面向公众访问的，部署前端项目，可以有手机APP，电脑网页；内网部署的是后端集群，前端在页面上操作发送请求到后端，在这途中会经过Nginx集群，Nginx把请求转交给API网关(springcloud gateway)（网关可以根据当前请求动态地路由到指定的服务，看当前请求是想调用商品服务还是购物车服务还是检索），从路由过来如果请求很多，可以负载均衡地调用商品服务器中一台（商品服务复制了多份），当商品服务器出现问题也可以在网关层面对服务进行熔断或降级（使用阿里的sentinel组件），网关还有其他的功能如认证授权、限流（只放行部分到服务器）等。</p>
<p>到达服务器后进行处理（springboot为微服务），服务与服务可能会相互调用（使用feign组件），有些请求可能经过登录才能进行（基于OAuth2.0的认证中心。安全和权限使用springSecurity控制）</p>
<p>服务可能保存了一些数据或者需要使用缓存，我们使用redis集群（分片+哨兵集群）。持久化使用mysql，读写分离和分库分表。</p>
<p>服务和服务之间会使用消息队列（RabbitMQ），来完成异步解耦，分布式事务的一致性。有些服务可能需要全文检索，检索商品信息，使用ElaticSearch。</p>
<p>服务可能需要存取数据，使用阿里云的对象存储服务OSS。</p>
<p>项目上线后为了快速定位问题，使用ELK对日志进行处理，使用LogStash收集业务里的各种日志，把日志存储到ES中，用Kibana可视化页面从ES中检索出相关信息，帮助我们快速定位问题所在。</p>
<p>在分布式系统中，由于我们每个服务都可能部署在很多台机器，服务和服务可能相互调用，就得知道彼此都在哪里，所以需要将所有服务都注册到注册中心。服务从注册中心发现其他服务所在位置（使用阿里Nacos作为注册中心）。</p>
<p>每个服务的配置众多，为了实现改一处配置相同配置就同步更改，就需要配置中心，也使用阿里的Nacos，服务从配置中心中动态取配置。</p>
<p>服务追踪，追踪服务调用链哪里出现问题，使用springcloud提供的Sleuth、Zipkin、Metrics，把每个服务的信息交给开源的Prometheus进行聚合分析，再由Grafana进行可视化展示，提供Prometheus提供的AlterManager实时得到服务的告警信息，以短信/邮件的方式告知服务开发人员。</p>
<p>还提供了持续集成和持续部署。项目发布起来后，因为微服务众多，每一个都打包部署到服务器太麻烦，有了持续集成后开发人员可以将修改后的代码提交到github，运维人员可以通过自动化工具Jenkins Pipeline将github中获取的代码打包成docker镜像，最终是由k8s集成docker服务，将服务以docker容器的方式运行。</p>
<p><strong>微服务划分图</strong>：</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.60cbl5inlng0.png" srcset="/img/loading.gif" lazyload alt="微服务划分图"></p>
<p>反映了需要创建的微服务以及相关技术。</p>
<p>前后分离开发。前端项目分为admin-vue（工作人员使用的后台管理系统）、shop-vue（面向公众访问的web网站）、app（公众）、小程序（公众）</p>
<p>商品服务：商品的增删改查、商品的上下架、商品详情<br>支付服务<br>优惠服务<br>用户服务：用户的个人中心、收货地址<br>仓储服务：商品的库存<br>秒杀服务：<br>订单服务：订单增删改查<br>检索服务：商品的检索ES<br>中央认证服务：登录、注册、单点登录、社交登录<br>购物车服务：<br>后台管理系统：添加优惠信息等</p>
<h1 id="二、分布式基础"><a href="#二、分布式基础" class="headerlink" title="二、分布式基础"></a>二、分布式基础</h1><h2 id="微服务"><a href="#微服务" class="headerlink" title="微服务"></a>微服务</h2><p>将单独的应用按照功能划分为一个一个的小服务，每个服务运行在自己的进程中，服务之间通过 HTTP 来进行通讯。</p>
<h2 id="集群-amp-分布式-amp-节点"><a href="#集群-amp-分布式-amp-节点" class="headerlink" title="集群&amp;分布式&amp;节点"></a>集群&amp;分布式&amp;节点</h2><p><strong>分布式</strong>是将不同的业务分布在不同的地方，协助工作</p>
<p><strong>集群</strong>是指一堆机器，是不是一起协助工作，谁也不知道</p>
<p><strong>节点</strong>是集群中的一台服务器，多个节点可以构成集群</p>
<p><strong>分布式中的每一个节点，都可以做集群。 而集群并不一定就是分布式的</strong></p>
<h2 id="远程调用"><a href="#远程调用" class="headerlink" title="远程调用"></a>远程调用</h2><p>SpringCloud 中使用 <strong>HTTP+JSON</strong> 的方式完成远程调用</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.3zvf3tw8e5y0.png" srcset="/img/loading.gif" lazyload alt="远程调用"></p>
<h2 id="负载均衡"><a href="#负载均衡" class="headerlink" title="负载均衡"></a>负载均衡</h2><p>在分布式系统中，每个服务可能在多台机器中都存在，那么在调用服务的时候，请求那台服务器就需要一个选择，为了使每一台服务器都不会出现太闲或太忙，可以使用负载均衡来控制访问哪台服务器。</p>
<p><strong>常见的负载均衡的算法：</strong></p>
<p>1、轮询：顺序选择服务器</p>
<p>2、最小连接：选择连接数最少的服务器</p>
<p>3、散列：通过请求原的 IP 做 hash 来选择服务器，这样可以在一定程度上保证同一个用户总能连接到同一台服务器</p>
<h2 id="服务注册-发现-amp-注册中心"><a href="#服务注册-发现-amp-注册中心" class="headerlink" title="服务注册/发现&amp;注册中心"></a>服务注册/发现&amp;注册中心</h2><p>当一个服务正常工作时，就可以在<strong>注册中心注册服务</strong>，这样这个服务就可以<strong>被发现</strong>从而被其他的<strong>服务调用</strong></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.17vywga06e2o.png" srcset="/img/loading.gif" lazyload alt="注册中心"></p>
<h2 id="配置中心"><a href="#配置中心" class="headerlink" title="配置中心"></a>配置中心</h2><p>每一个服务最终都有大量的配置，并且每个服务都可能部署在多台机器上。我们经常需要变更配置，我们可以让每个服务在配置中心获取自己的配置</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.5torblti7ws0.png" srcset="/img/loading.gif" lazyload alt="配置中心"></p>
<h2 id="服务熔断-amp-服务降级"><a href="#服务熔断-amp-服务降级" class="headerlink" title="服务熔断&amp;服务降级"></a>服务熔断&amp;服务降级</h2><p>多个服务之间相互依赖，当一个服务出现问题时，如果不进行处理，那个一个请求无法处理完成，后面的请求都堆积，可能会造成雪崩效应</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210925/image-20210923211944388.64zt4npjpww0.png" srcset="/img/loading.gif" lazyload alt="服务熔断&amp;服务降级"></p>
<p><strong>服务熔断：</strong></p>
<p>当一个服务响应超时时，并且之前也经常请求失败，那么就会开启断路保护机制，在下一次请求的时候就不在调用这个服务了，而是直接返回本地准备好的数据，这样就不会导致请求的积压</p>
<p><strong>服务降级：</strong></p>
<p>当系统处在高峰期，系统资源紧张的时候，可以让一些非核心的业务降级运行，即直接不处理请求或直接返回简单处理数据。</p>
<h2 id="API-网关"><a href="#API-网关" class="headerlink" title="API 网关"></a>API 网关</h2><p>客户端发送请求到服务器路途中，设置一个网关，<strong>请求都先到达网关，网关对请求进行统一认证</strong>（合法非法）和处理等操作。他是安检。</p>
<p>在微服务架构中，API gateway 作为整体架构的重要组件，它抽象了微服务中都需要的公共功能，同时提供了客户端<strong>负载均衡，服务自动熔断，灰度发布，统一认证，限流流控，日志统计</strong>等丰富的功能，帮助我们解决很多 API 管理难题。</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.73e6vg0a6wo0.png" srcset="/img/loading.gif" lazyload alt="API网关"></p>
<h1 id="三、基础环境搭建"><a href="#三、基础环境搭建" class="headerlink" title="三、基础环境搭建"></a>三、基础环境搭建</h1><p>首先要准备一台 Linux 主机，可以是本地虚拟机，也可以是云服务器。</p>
<h2 id="docker-安装"><a href="#docker-安装" class="headerlink" title="docker 安装"></a>docker 安装</h2><p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.7d76mynb2es0.png" srcset="/img/loading.gif" lazyload alt="docker"></p>
<p>参考 docker <a target="_blank" rel="noopener" href="https://docs.docker.com/engine/install/centos/">官网</a> 在 CentOS 中的安装</p>
<p>需要使用 root 用户权限</p>
<p>1、卸载旧版本</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs shell">yum remove docker \<br>                  docker-client \<br>                  docker-client-latest \<br>                  docker-common \<br>                  docker-latest \<br>                  docker-latest-logrotate \<br>                  docker-logrotate \<br>                  docker-engine<br></code></pre></td></tr></table></figure>

<p>2、安装<code>yum-utils</code>包</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">yum install -y yum-utils<br></code></pre></td></tr></table></figure>

<p>3、设置<strong>稳定</strong>存储库。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs shell">yum-config-manager \<br>    --add-repo \<br>    https://download.docker.com/linux/centos/docker-ce.repo<br></code></pre></td></tr></table></figure>

<p>4、安装<em>最新版本</em>的 Docker Engine 和 containerd</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">yum install docker-ce docker-ce-cli containerd.io<br></code></pre></td></tr></table></figure>

<p>5、启动 Docker</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">systemctl start docker<br></code></pre></td></tr></table></figure>

<p>6、通过运行<code>hello-world</code> 映像验证 Docker Engine 是否已正确安装</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">docker run hello-world<br></code></pre></td></tr></table></figure>

<p>通过 <code>docker images</code> 查看下载的 docker 镜像，使用 <code>docker ps -a</code> 查看创建的所有容器</p>
<p>7、设置 docker 开机自启动</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">systemctl enable docker<br></code></pre></td></tr></table></figure>

<p>8、运行容器</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs shell"><span class="hljs-meta">#</span><span class="bash"> 我们接下来设置我们要用的容器每次都是自动启动</span><br>docker update redis --restart=always<br>docker update mysql --restart=always<br><span class="hljs-meta">#</span><span class="bash"> 如果不配置上面的内容的话，我们也可以选择手动启动</span><br>docker start mysql<br>docker start redis<br></code></pre></td></tr></table></figure>



<h2 id="在-docker-中安装-mysql"><a href="#在-docker-中安装-mysql" class="headerlink" title="在 docker 中安装 mysql"></a>在 docker 中安装 mysql</h2><p>查看官方提供的 mysql 镜像：<a target="_blank" rel="noopener" href="https://hub.docker.com/_/mysql?tab=tags">https://hub.docker.com/_/mysql?tab=tags</a></p>
<p><strong>这里下载 mysql 5.7 版本</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">docker pull mysql:5.7<br></code></pre></td></tr></table></figure>

<p>如果要下载最新版</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">docker pull mysql<br></code></pre></td></tr></table></figure>

<p><strong>创建实例并启动</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">docker run -p 3306:3306 --name mysql -v /mydata/mysql/log:/var/log/mysql -v /mydata/mysql/data:/var/lib/mysql -v /mydata/mysql/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7<br></code></pre></td></tr></table></figure>

<p>参数说明</p>
<p>-p 3306:3306：将容器的 3306 端口映射到主机的 3306 端口 </p>
<p>-v /mydata/mysql/conf:/etc/mysql：将配置文件夹挂载到主机 </p>
<p>-v /mydata/mysql/log:/var/log/mysql：将日志文件夹挂载到主机 </p>
<p>-v /mydata/mysql/data:/var/lib/mysql/：将配置文件夹挂载到主机 </p>
<p>-e MYSQL_ROOT_PASSWORD=123456：初始化 root 用户的密码</p>
<p>-d mysql:5.7：指定mysql镜像版本，如果本地没有TAG 5.7 的镜像就会默认去官网pull 5.7的镜像。</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.593isf8v3mw0.png" srcset="/img/loading.gif" lazyload alt="端口映射"></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.7cjy35m4hf40.png" srcset="/img/loading.gif" lazyload alt="docker容器文件挂载"></p>
<p><strong>配置 mysql</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs shell">vim /mydata/mysql/conf/my.cnf<br><br>[client] <br>default-character-set=utf8 <br><br>[mysql] <br>default-character-set=utf8 <br><br>[mysqld] <br>init_connect=&#x27;SET collation_connection = utf8_unicode_ci&#x27; <br>init_connect=&#x27;SET NAMES utf8&#x27; <br>character-set-server=utf8 <br>collation-server=utf8_unicode_ci <br>skip-character-set-client-handshake <br>skip-name-resolve<br></code></pre></td></tr></table></figure>

<p><strong>通过容器的 mysql 命令工具连接数据库</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">docker exec -it mysql mysql -uroot -p123456<br></code></pre></td></tr></table></figure>

<p><strong>设置 root 远程访问</strong></p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-string">grant</span> <span class="hljs-string">all</span> <span class="hljs-string">privileges</span> <span class="hljs-string">on</span> <span class="hljs-string">*.*</span> <span class="hljs-string">to</span> <span class="hljs-string">&#x27;root&#x27;</span><span class="hljs-string">@&#x27;%&#x27;</span> <span class="hljs-string">identified</span> <span class="hljs-string">by</span> <span class="hljs-string">&#x27;123456&#x27;</span> <span class="hljs-string">with</span> <span class="hljs-string">grant</span> <span class="hljs-string">option;</span><br><br><span class="hljs-string">flush</span> <span class="hljs-string">privileges;</span><br></code></pre></td></tr></table></figure>

<p>关闭服务器防火墙或者开放 3306 端口后就可以使用本地可视化工具访问</p>
<p>操作防火墙</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-string">启动：</span> <span class="hljs-string">systemctl</span> <span class="hljs-string">start</span> <span class="hljs-string">firewalld</span><br><br><span class="hljs-string">查看状态：</span> <span class="hljs-string">systemctl</span> <span class="hljs-string">status</span> <span class="hljs-string">firewalld</span> <br><br><span class="hljs-string">停止：</span> <span class="hljs-string">systemctl</span> <span class="hljs-string">disable</span> <span class="hljs-string">firewalld</span><br><br><span class="hljs-string">禁用：</span> <span class="hljs-string">systemctl</span> <span class="hljs-string">stop</span> <span class="hljs-string">firewalld</span><br></code></pre></td></tr></table></figure>

<p>开放端口</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-string">查看想开的端口是否已开：firewall-cmd</span> <span class="hljs-string">--query-port=123/tcp</span><br><br><span class="hljs-string">添加指定需要开放的端口：firewall-cmd</span> <span class="hljs-string">--add-port=123/tcp</span> <span class="hljs-string">--permanent</span><br><br><span class="hljs-string">重载入添加的端口：firewall-cmd</span> <span class="hljs-string">--reload</span><br><br><span class="hljs-string">查询指定端口是否开启成功：firewall-cmd</span> <span class="hljs-string">--query-port=123/tcp</span><br><br><span class="hljs-string">移除指定端口：firewall-cmd</span> <span class="hljs-string">--permanent</span> <span class="hljs-string">--remove-port=123/tcp</span><br></code></pre></td></tr></table></figure>



<h2 id="在-docker-中安装-redis"><a href="#在-docker-中安装-redis" class="headerlink" title="在 docker 中安装 redis"></a>在 docker 中安装 redis</h2><p><strong>下载镜像</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">docker pull redis<br></code></pre></td></tr></table></figure>

<p><strong>创建实例并启动</strong></p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-comment"># 首先要创建一个目录和 redis.conf 文件</span><br><span class="hljs-string">mkdir</span> <span class="hljs-string">-p</span> <span class="hljs-string">/mydata/redis/conf</span> <br><span class="hljs-string">touch</span> <span class="hljs-string">/mydata/redis/conf/redis.conf</span> <br><br><span class="hljs-comment"># 创建实例并启动</span><br><span class="hljs-string">docker</span> <span class="hljs-string">run</span> <span class="hljs-string">-p</span> <span class="hljs-number">6379</span><span class="hljs-string">:6379</span> <span class="hljs-string">--name</span> <span class="hljs-string">redis</span> <span class="hljs-string">-v</span> <span class="hljs-string">/mydata/redis/data:/data</span> <span class="hljs-string">-v</span> <span class="hljs-string">/mydata/redis/conf/redis.conf:/etc/redis/redis.conf</span> <span class="hljs-string">-d</span> <span class="hljs-string">redis</span> <span class="hljs-string">redis-server</span> <span class="hljs-string">/etc/redis/redis.conf</span><br></code></pre></td></tr></table></figure>

<p><strong>配置 redis 中数据可以持久化保存</strong>，在 redis.conf 中添加配置</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">appendonly yes<br></code></pre></td></tr></table></figure>

<p>其他配置见官网：<a target="_blank" rel="noopener" href="https://raw.githubusercontent.com/antirez/redis/4.0/redis.conf">https://raw.githubusercontent.com/antirez/redis/4.0/redis.conf</a></p>
<p>使用 redis 镜像执行 redis-cli 命令连接：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">docker exec -it redis redis-cli<br></code></pre></td></tr></table></figure>



<h2 id="创建项目"><a href="#创建项目" class="headerlink" title="创建项目"></a>创建项目</h2><p>在 gitee 中创建仓库，托管我们的代码</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.2z2zagyjg5u0.png" srcset="/img/loading.gif" lazyload alt="gitee创建项目"></p>
<p>在 IDEA 中导入项目，创建 springboot 服务，主要有 <strong>商品服务、仓储服务、订单服务、优惠券服务、用户服务</strong></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210923/image.4eyxvftgiiw0.png" srcset="/img/loading.gif" lazyload alt="创建的服务"></p>
<p>在根目录中创建总的 pom.xml 文件，作为创建的服务的父项目</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">project</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://maven.apache.org/POM/4.0.0&quot;</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span><br><span class="hljs-tag">   <span class="hljs-attr">xsi:schemaLocation</span>=<span class="hljs-string">&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">modelVersion</span>&gt;</span>4.0.0<span class="hljs-tag">&lt;/<span class="hljs-name">modelVersion</span>&gt;</span><br><br>   <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>cn.yechen.gulimall<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>gulimall<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>0.0.1-SNAPSHOT<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>gulimall-parent<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">description</span>&gt;</span>谷粒商城<span class="hljs-tag">&lt;/<span class="hljs-name">description</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">packaging</span>&gt;</span>pom<span class="hljs-tag">&lt;/<span class="hljs-name">packaging</span>&gt;</span><br><br>   <span class="hljs-tag">&lt;<span class="hljs-name">modules</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-coupon<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-member<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-order<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-product<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-ware<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>renren-fast<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;/<span class="hljs-name">modules</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">project</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>配置根目录下的 .gitingnore 文件，来指定上传时要排除的一些文件</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs txt">target/<br>pom.xml.tag<br>pom.xml.releaseBackup<br>pom.xml.versionsBackup<br>pom.xml.next<br>release.properties<br>dependency-reduced-pom.xml<br>buildNumber.properties<br>.mvn/timing.properties<br>.mvn/wrapper/maven-wrapper.jar<br><br>**/mvnw<br>**/mvnw.cmd<br><br>**/.mvn<br>**/target/<br><br>.idea<br>**/.gitignore<br></code></pre></td></tr></table></figure>

<h2 id="创建数据库"><a href="#创建数据库" class="headerlink" title="创建数据库"></a>创建数据库</h2><p>数据库：<a target="_blank" rel="noopener" href="https://gitee.com/yechen-ops/gulimall/tree/master/sql">https://gitee.com/yechen-ops/gulimall/tree/master/sql</a></p>
<p>注意运行就行，参考自 <a target="_blank" rel="noopener" href="https://github.com/FermHan/gulimall">https://github.com/FermHan/gulimall</a></p>
<h2 id="项目快速构建"><a href="#项目快速构建" class="headerlink" title="项目快速构建"></a>项目快速构建</h2><p><strong>使用人人开源快速构建项目前后端项目</strong></p>
<p>开源地址：</p>
<p>后端：<a target="_blank" rel="noopener" href="https://gitee.com/renrenio/renren-fast">https://gitee.com/renrenio/renren-fast</a></p>
<p>前端：<a target="_blank" rel="noopener" href="https://gitee.com/renrenio/renren-fast-vue">https://gitee.com/renrenio/renren-fast-vue</a></p>
<p>下载：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs shell"><span class="hljs-meta">#</span><span class="bash"> 前端</span><br>git clone https://gitee.com/renrenio/renren-fast-vue.git<br><span class="hljs-meta">#</span><span class="bash"> 后端</span><br>git clone https://gitee.com/renrenio/renren-fast.git<br></code></pre></td></tr></table></figure>



<h3 id="后端项目"><a href="#后端项目" class="headerlink" title="后端项目"></a>后端项目</h3><p>删除文件中的 .git 文件后将 renren-fast 文件放入我们的父项目中，作为项目的一个模块，注意这里 springboot 的版本不要该，改了会有点问题，为了不引起不必要的麻烦，就用指定的版本就行。</p>
<p>在父项目的 pom.xml 文件中指定这个模块</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">modules</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-coupon<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-member<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-order<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-product<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-ware<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>renren-fast<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">modules</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>修改 renren-fast 模块中的主配置文件（application-dev.yml），修改数据库信息</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">spring:</span><br>    <span class="hljs-attr">datasource:</span><br>        <span class="hljs-attr">type:</span> <span class="hljs-string">com.alibaba.druid.pool.DruidDataSource</span><br>        <span class="hljs-attr">druid:</span><br>            <span class="hljs-attr">driver-class-name:</span> <span class="hljs-string">com.mysql.cj.jdbc.Driver</span><br>            <span class="hljs-attr">url:</span> <span class="hljs-string">jdbc:mysql://192.168.126.99:3306/gulimall_admin?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;useSSL=false</span><br>            <span class="hljs-attr">username:</span> <span class="hljs-string">root</span><br>            <span class="hljs-attr">password:</span> <span class="hljs-number">123456</span><br></code></pre></td></tr></table></figure>

<p>之后就可以启动项目了，但因为这个项目是前后端分离的，因此要配合前端项目使用。</p>
<p>浏览器输入<a target="_blank" rel="noopener" href="http://localhost:8080/renren-fast/">http://localhost:8080/renren-fast/</a>  得到 {“msg”:“invalid token”,“code”:401} 就代表无误</p>
<h3 id="前端项目"><a href="#前端项目" class="headerlink" title="前端项目"></a>前端项目</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">npm install<br></code></pre></td></tr></table></figure>

<p>但是此时大概率是会出错的，解决方法可以参考 <a target="_blank" rel="noopener" href="https://blog.csdn.net/hancoder/article/details/113821646">https://blog.csdn.net/hancoder/article/details/113821646</a></p>
<p>主要是 node-sass 版本问题，他的版本看和 node 版本对应</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210924/image.22irl60gcku8.png" srcset="/img/loading.gif" lazyload alt="node-sass与node版本对应"></p>
<p>我这里查看 node 版本是 </p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210924/image.5dp8iyjqyqo0.png" srcset="/img/loading.gif" lazyload alt="我的node版本"></p>
<p>因此我需要的 node-sass 为 4.14+ 版本，但此时我们看 package.json 中的 node-sass 版本</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-string">&quot;node-sass&quot;</span>: <span class="hljs-string">&quot;4.13.1&quot;</span>,<br></code></pre></td></tr></table></figure>

<p>所以下载依赖不成功</p>
<p><strong>解决方法：</strong></p>
<p>先下载对应版本的 node-sass，在下载其他依赖</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs shell"><span class="hljs-meta">#</span><span class="bash"> 指定node-sass版本，这句等价于修改package.json文件了。</span><br><span class="hljs-meta">#</span><span class="bash"> 注意不要指定4.9.2了</span><br>npm install  node-sass@4.14<br><span class="hljs-meta"></span><br><span class="hljs-meta">#</span><span class="bash">安装其他依赖：</span><br>npm install<br><span class="hljs-meta"></span><br><span class="hljs-meta">#</span><span class="bash"> 启动项目：</span><br>npm run dev<br></code></pre></td></tr></table></figure>

<p><strong>亲测有效！！！</strong></p>
<h2 id="逆向工程生成代码"><a href="#逆向工程生成代码" class="headerlink" title="逆向工程生成代码"></a>逆向工程生成代码</h2><p>使用人人开源提供的代码生成器，可在线生成 entity、xml、dao、service、html、js、sql 代码，减少70%以上的开发任务</p>
<p><strong>下载：</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">git clone https://gitee.com/renrenio/renren-generator.git<br></code></pre></td></tr></table></figure>

<p>删除目录中的 .git 文件，将整个文件放入到 gulimall 父项目中，成为项目的一个模块</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">modules</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-coupon<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-member<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-order<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-product<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>gulimall-ware<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>renren-fast<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>renren-generator<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">modules</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>配置 renren-generator 模块下的 application.yml 文件，配置一下 mysql 的一些数据，这里首先生成商品相关的文件，之后要生成其他表，只要修改这里的表名就可以了</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-comment"># mysql</span><br><span class="hljs-attr">spring:</span><br>  <span class="hljs-attr">datasource:</span><br>    <span class="hljs-attr">type:</span> <span class="hljs-string">com.alibaba.druid.pool.DruidDataSource</span><br>    <span class="hljs-comment">#MySQL配置</span><br>    <span class="hljs-attr">driverClassName:</span> <span class="hljs-string">com.mysql.cj.jdbc.Driver</span><br>    <span class="hljs-attr">url:</span> <span class="hljs-string">jdbc:mysql://192.168.126.99:3306/gulimall_pms?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;useSSL=false</span><br>    <span class="hljs-attr">username:</span> <span class="hljs-string">root</span><br>    <span class="hljs-attr">password:</span> <span class="hljs-number">123456</span><br></code></pre></td></tr></table></figure>

<p>在修改 generator.properties 文件，配置一下逆向工程的一些参数，之后要修改就修改第六行的 moduleName 和第 12 行表的前缀 tablePrefix 就可以了</p>
<figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><code class="hljs properties"><span class="hljs-comment">#代码生成器，配置信息</span><br><br><span class="hljs-attr">mainPath</span>=<span class="hljs-string">cn.yechen.gulimall</span><br><span class="hljs-comment">#包名</span><br><span class="hljs-attr">package</span>=<span class="hljs-string">cn.yechen.gulimall</span><br><span class="hljs-attr">moduleName</span>=<span class="hljs-string">product</span><br><span class="hljs-comment">#作者</span><br><span class="hljs-attr">author</span>=<span class="hljs-string">yechen</span><br><span class="hljs-comment">#Email</span><br><span class="hljs-attr">email</span>=<span class="hljs-string">15715830811@163.com</span><br><span class="hljs-comment">#表前缀(类名不会包含表前缀)</span><br><span class="hljs-attr">tablePrefix</span>=<span class="hljs-string">pms_</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">#类型转换，配置信息</span><br><span class="hljs-attr">tinyint</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">smallint</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">mediumint</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">int</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">integer</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">bigint</span>=<span class="hljs-string">Long</span><br><span class="hljs-attr">float</span>=<span class="hljs-string">Float</span><br><span class="hljs-attr">double</span>=<span class="hljs-string">Double</span><br><span class="hljs-attr">decimal</span>=<span class="hljs-string">BigDecimal</span><br><span class="hljs-attr">bit</span>=<span class="hljs-string">Boolean</span><br><br><span class="hljs-attr">char</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">varchar</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">tinytext</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">text</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">mediumtext</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">longtext</span>=<span class="hljs-string">String</span><br><br><br><span class="hljs-attr">date</span>=<span class="hljs-string">Date</span><br><span class="hljs-attr">datetime</span>=<span class="hljs-string">Date</span><br><span class="hljs-attr">timestamp</span>=<span class="hljs-string">Date</span><br><br><span class="hljs-attr">NUMBER</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">INT</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">INTEGER</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">BINARY_INTEGER</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">LONG</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">FLOAT</span>=<span class="hljs-string">Float</span><br><span class="hljs-attr">BINARY_FLOAT</span>=<span class="hljs-string">Float</span><br><span class="hljs-attr">DOUBLE</span>=<span class="hljs-string">Double</span><br><span class="hljs-attr">BINARY_DOUBLE</span>=<span class="hljs-string">Double</span><br><span class="hljs-attr">DECIMAL</span>=<span class="hljs-string">BigDecimal</span><br><span class="hljs-attr">CHAR</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">VARCHAR</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">VARCHAR2</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">NVARCHAR</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">NVARCHAR2</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">CLOB</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">BLOB</span>=<span class="hljs-string">String</span><br><span class="hljs-attr">DATE</span>=<span class="hljs-string">Date</span><br><span class="hljs-attr">DATETIME</span>=<span class="hljs-string">Date</span><br><span class="hljs-attr">TIMESTAMP</span>=<span class="hljs-string">Date</span><br><span class="hljs-meta">TIMESTAMP(6)</span>=<span class="hljs-string">Date</span><br><br><span class="hljs-attr">int8</span>=<span class="hljs-string">Long</span><br><span class="hljs-attr">int4</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">int2</span>=<span class="hljs-string">Integer</span><br><span class="hljs-attr">numeric</span>=<span class="hljs-string">BigDecimal</span><br><br><span class="hljs-attr">nvarchar</span>=<span class="hljs-string">String</span><br></code></pre></td></tr></table></figure>

<p>之后，就可以运行 RenrenApplication，访问 <a target="_blank" rel="noopener" href="http://localhost/">http://localhost</a> 就可以访问到逆向生成器的页面了</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210925/image.32mzemksp9m0.png" srcset="/img/loading.gif" lazyload alt="代码生成器"></p>
<p>全选表格生成文件，解压后将文件放入到模块对应的文件夹中即可</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210925/image.a8rhuh1azc4.png" srcset="/img/loading.gif" lazyload alt="gulimall-product模块导入文件"></p>
<p>但此时我们会发现，不管是 controller、service 还是 dao 中都会有报错，这是缺少了相关依赖造成的，我们会创建公共依赖模块解决</p>
<h2 id="创建公共依赖"><a href="#创建公共依赖" class="headerlink" title="创建公共依赖"></a>创建公共依赖</h2><p>创建一个普通的 maven 工程，作为 gulimall 的子模块，这个模块作为所有微服务都依赖的公共部分，提供微服务所需要的公共依赖。</p>
<p>在 gulimall-product 模块的 pom.xml 文件中依赖 gulimall-common</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span><br>   <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>cn.yechen<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>gulimall-common<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>0.0.1-SNAPSHOT<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>   <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>因此我们之后在 common 模块中加入公共依赖，product 等微服务模块都能依赖到了</p>
<p>那么现在就可以下 common 模块中添加依赖了，查看 controller、service、dao、entity 中需要的依赖，在 pom.xml 文件中添加</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- mybatis-plus --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.baomidou<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mybatis-plus-boot-starter<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.4.3.1<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- lombok --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.projectlombok<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>lombok<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.18.20<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- httpcomponent包。发送http请求 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.httpcomponents<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>httpcore<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>4.4.14<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>commons-lang<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>commons-lang<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.6<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- mysql 驱动 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>mysql<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mysql-connector-java<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>8.0.17<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- servlet --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>javax.servlet<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>servlet-api<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.5<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>provided<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>同时还有依赖了人人开源自己写的一下工具类，我们可以直接在 renren-fast 模块中拷贝相关的类到 common 模块中，完成类的依赖</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210925/image.24uyb5tcf534.png" srcset="/img/loading.gif" lazyload alt="目前common中需要的类"></p>
<p>通过完善 common 模块的依赖，可以发现 product 模块中的大部分文件已经不报错了，但还是有一个问题</p>
<p>例如在 <code>AttrAttrgroupRelationController</code> 中的</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 列表</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@RequestMapping(&quot;/list&quot;)</span><br><span class="hljs-meta">@RequiresPermissions(&quot;product:attrattrgrouprelation:list&quot;)</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> R <span class="hljs-title">list</span><span class="hljs-params">(<span class="hljs-meta">@RequestParam</span> Map&lt;String, Object&gt; params)</span></span>&#123;<br>    PageUtils page = attrAttrgroupRelationService.queryPage(params);<br><br>    <span class="hljs-keyword">return</span> R.ok().put(<span class="hljs-string">&quot;page&quot;</span>, page);<br>&#125;<br></code></pre></td></tr></table></figure>

<p><code>@RequiresPermissions</code> 注解是 <code>shiro</code> 提供的做权限控制的，我们现在暂时还用不到，因此我们可以将他全部注释的掉，但这样有太麻烦了</p>
<p>有一个方法，直接更改代码生成器中对于 controller 生成的末班，将这个功能注释的掉</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210925/image.2yg8gpo9x420.png" srcset="/img/loading.gif" lazyload alt="controller生成模板"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">package</span> $&#123;<span class="hljs-keyword">package</span>&#125;.$&#123;moduleName&#125;.controller;<br><br><span class="hljs-keyword">import</span> java.util.Arrays;<br><span class="hljs-keyword">import</span> java.util.Map;<br><br><span class="hljs-keyword">import</span> org.springframework.beans.factory.annotation.Autowired;<br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.PathVariable;<br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestBody;<br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;<br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestParam;<br><span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RestController;<br><br><span class="hljs-keyword">import</span> $&#123;<span class="hljs-keyword">package</span>&#125;.$&#123;moduleName&#125;.entity.$&#123;className&#125;Entity;<br><span class="hljs-keyword">import</span> $&#123;<span class="hljs-keyword">package</span>&#125;.$&#123;moduleName&#125;.service.$&#123;className&#125;Service;<br><span class="hljs-keyword">import</span> $&#123;mainPath&#125;.common.utils.PageUtils;<br><span class="hljs-keyword">import</span> $&#123;mainPath&#125;.common.utils.R;<br><br><br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * $&#123;comments&#125;</span><br><span class="hljs-comment"> *</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author</span> $&#123;author&#125;</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@email</span> $&#123;email&#125;</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@date</span> $&#123;datetime&#125;</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@RestController</span><br><span class="hljs-meta">@RequestMapping(&quot;$&#123;moduleName&#125;/$&#123;pathName&#125;&quot;)</span><br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> $</span>&#123;className&#125;Controller &#123;<br>    <span class="hljs-meta">@Autowired</span><br>    <span class="hljs-keyword">private</span> $&#123;className&#125;Service $&#123;classname&#125;Service;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 列表</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@RequestMapping(&quot;/list&quot;)</span><br>    <span class="hljs-comment">//@RequiresPermissions(&quot;$&#123;moduleName&#125;:$&#123;pathName&#125;:list&quot;)</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> R <span class="hljs-title">list</span><span class="hljs-params">(<span class="hljs-meta">@RequestParam</span> Map&lt;String, Object&gt; params)</span></span>&#123;<br>        PageUtils page = $&#123;classname&#125;Service.queryPage(params);<br><br>        <span class="hljs-keyword">return</span> R.ok().put(<span class="hljs-string">&quot;page&quot;</span>, page);<br>    &#125;<br><br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 信息</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@RequestMapping(&quot;/info/&#123;$&#123;pk.attrname&#125;&#125;&quot;)</span><br>    <span class="hljs-comment">//@RequiresPermissions(&quot;$&#123;moduleName&#125;:$&#123;pathName&#125;:info&quot;)</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> R <span class="hljs-title">info</span><span class="hljs-params">(<span class="hljs-meta">@PathVariable(&quot;$&#123;pk.attrname&#125;&quot;)</span> $&#123;pk.attrType&#125; $&#123;pk.attrname&#125;)</span></span>&#123;<br>		$&#123;className&#125;Entity $&#123;classname&#125; = $&#123;classname&#125;Service.getById($&#123;pk.attrname&#125;);<br><br>        <span class="hljs-keyword">return</span> R.ok().put(<span class="hljs-string">&quot;$&#123;classname&#125;&quot;</span>, $&#123;classname&#125;);<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 保存</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@RequestMapping(&quot;/save&quot;)</span><br>    <span class="hljs-comment">//@RequiresPermissions(&quot;$&#123;moduleName&#125;:$&#123;pathName&#125;:save&quot;)</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> R <span class="hljs-title">save</span><span class="hljs-params">(<span class="hljs-meta">@RequestBody</span> $&#123;className&#125;Entity $&#123;classname&#125;)</span></span>&#123;<br>		$&#123;classname&#125;Service.save($&#123;classname&#125;);<br><br>        <span class="hljs-keyword">return</span> R.ok();<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 修改</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@RequestMapping(&quot;/update&quot;)</span><br>    <span class="hljs-comment">//@RequiresPermissions(&quot;$&#123;moduleName&#125;:$&#123;pathName&#125;:update&quot;)</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> R <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-meta">@RequestBody</span> $&#123;className&#125;Entity $&#123;classname&#125;)</span></span>&#123;<br>		$&#123;classname&#125;Service.updateById($&#123;classname&#125;);<br><br>        <span class="hljs-keyword">return</span> R.ok();<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 删除</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@RequestMapping(&quot;/delete&quot;)</span><br>    <span class="hljs-comment">//@RequiresPermissions(&quot;$&#123;moduleName&#125;:$&#123;pathName&#125;:delete&quot;)</span><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> R <span class="hljs-title">delete</span><span class="hljs-params">(<span class="hljs-meta">@RequestBody</span> $&#123;pk.attrType&#125;[] $&#123;pk.attrname&#125;s)</span></span>&#123;<br>		$&#123;classname&#125;Service.removeByIds(Arrays.asList($&#123;pk.attrname&#125;s));<br><br>        <span class="hljs-keyword">return</span> R.ok();<br>    &#125;<br><br>&#125;<br><br></code></pre></td></tr></table></figure>

<p>这样 controller 中就不使用 <code>@RequiresPermissions</code> 了</p>
<h2 id="测试-product-模块"><a href="#测试-product-模块" class="headerlink" title="测试 product 模块"></a>测试 product 模块</h2><p><strong>测试一下 product 模块是否可以进行简单的 CURD</strong></p>
<ol>
<li>在 application.yml 文件中添加数据库配置及端口配置</li>
</ol>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">spring:</span><br>  <span class="hljs-attr">datasource:</span><br>    <span class="hljs-comment">#MySQL配置</span><br>    <span class="hljs-attr">driverClassName:</span> <span class="hljs-string">com.mysql.cj.jdbc.Driver</span><br>    <span class="hljs-attr">url:</span> <span class="hljs-string">jdbc:mysql://192.168.126.99:3306/gulimall_pms?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;useSSL=false</span><br>    <span class="hljs-attr">username:</span> <span class="hljs-string">root</span><br>    <span class="hljs-attr">password:</span> <span class="hljs-number">123456</span><br><span class="hljs-attr">mybatis-plus:</span><br>  <span class="hljs-attr">mapper-locations:</span> <span class="hljs-string">classpath:/mapper/**/*.xml</span><br>  <span class="hljs-attr">global-config:</span><br>    <span class="hljs-attr">db-config:</span><br>      <span class="hljs-attr">id-type:</span> <span class="hljs-string">auto</span><br><span class="hljs-attr">server:</span><br>  <span class="hljs-attr">port:</span> <span class="hljs-number">10000</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>classpath 和 classpath* 区别：<br>classpath：只会到你的 class 路径中查找找文件;<br>classpath*：不仅包含 class 路径，还包括 jar 文件中(class 路径) 进行查找</p>
<p>classpath *的使用：当项目中有多个 classpath 路径，并同时加载多个 classpath 路径下（此种情况多数不会遇到）的文件，*就发挥了作用，如果不加*，则表示仅仅加载第一个 classpath 路径。</p>
</blockquote>
<ol start="2">
<li>在启动类上添加 mapper 扫描</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@MapperScan(&quot;cn.yechen.gulimall.product.dao&quot;)</span><br><span class="hljs-meta">@SpringBootApplication</span><br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GulimallProductApplication</span> </span>&#123;<br><br>   <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>&#123;<br>      SpringApplication.run(GulimallProductApplication.class, args);<br>   &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>

<p>之后就可以选择任意一个之前生成的 controller 接口，访问获取数据，如访问 <a target="_blank" rel="noopener" href="http://localhost:10000/product/brand/list">http://localhost:10000/product/brand/list</a> 获取所有的品牌列表</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210925/image.9f0ztmkfpo0.png" srcset="/img/loading.gif" lazyload alt="获取到数据"></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210925/image.28xgtvg3ayo0.png" srcset="/img/loading.gif" lazyload alt="数据库中数据"></p>
<p>再之后就是更改代码生成器配置，生成不同模块的代码了，这是一个重复的工作，慢慢做，细心点，就没有任何问题</p>
<p><strong>操作步骤：</strong></p>
<ol>
<li>使用代码生成器生成对应代码（更改 application.yml 和 generator.properties 文件）</li>
<li>引入 common 模块</li>
<li>配置 application.yml </li>
<li>配置启动类</li>
<li>启动服务测试接口</li>
</ol>
<h1 id="四、相关数据说明"><a href="#四、相关数据说明" class="headerlink" title="四、相关数据说明"></a>四、相关数据说明</h1><h2 id="服务设置"><a href="#服务设置" class="headerlink" title="服务设置"></a>服务设置</h2><p><strong>这里列出模块名、表名前缀名及服务端口（这个随自己设置）的对应关系：</strong></p>
<table>
<thead>
<tr>
<th align="center">模块名</th>
<th align="center">服务名称</th>
<th align="center">表名前缀</th>
<th align="center">服务端口</th>
</tr>
</thead>
<tbody><tr>
<td align="center">gulimall-coupon</td>
<td align="center">优惠券服务</td>
<td align="center">sms_</td>
<td align="center">7000</td>
</tr>
<tr>
<td align="center">gulimall-member</td>
<td align="center">用户服务</td>
<td align="center">ums_</td>
<td align="center">8000</td>
</tr>
<tr>
<td align="center">gulimall-order</td>
<td align="center">订单服务</td>
<td align="center">oms_</td>
<td align="center">9000</td>
</tr>
<tr>
<td align="center">gulimall-product</td>
<td align="center">商品服务</td>
<td align="center">pms_</td>
<td align="center">10000</td>
</tr>
<tr>
<td align="center">gulimall-ware</td>
<td align="center">仓储服务</td>
<td align="center">wms_</td>
<td align="center">11000</td>
</tr>
</tbody></table>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/categories/Java-%E9%A1%B9%E7%9B%AE/">Java 项目</a>
                    
                      <a class="hover-with-bg" href="/categories/Java-%E9%A1%B9%E7%9B%AE/%E8%B0%B7%E7%B2%92%E5%95%86%E5%9F%8E/">谷粒商城</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/Java-%E9%A1%B9%E7%9B%AE/">Java 项目</a>
                    
                      <a class="hover-with-bg" href="/tags/%E8%B0%B7%E7%B2%92%E5%95%86%E5%9F%8E/">谷粒商城</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2021/09/25/%E8%B0%B7%E7%B2%92%E5%95%86%E5%9F%8E%E9%A1%B9%E7%9B%AE-2021-09-25-2-%E5%88%86%E5%B8%83%E5%BC%8F%E7%BB%84%E4%BB%B6/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">2.分布式组件</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2021/09/16/Spring%E6%B3%A8%E8%A7%A3%E5%BC%80%E5%8F%91%E4%B9%8B%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C/">
                        <span class="hidden-mobile">Spring注解开发之组件注册</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>


  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>

<!-- Plugins -->


  
    <script  src="/js/img-lazyload.js" ></script>
  



  



  <script  src="https://cdn.jsdelivr.net/npm/tocbot@4.12.3/dist/tocbot.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4.3.1/anchor.min.js" ></script>



  <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js" ></script>



  <script  src="/js/local-search.js" ></script>






  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2.0.12/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>














  
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/xiaoxuehua.js"></script>
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/caidai.js"></script>
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/love.js"></script>
<script src="//cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
<script src="//cdn.jsdelivr.net/gh/metowolf/MetingJS@1.2/dist/Meting.min.js"></script>



<!-- 主题的启动项 保持在最底部 -->
<script  src="/js/boot.js" ></script>

  <!--动态线条背景-->
  <script type="text/javascript" color="70,119,184" opacity='1' zIndex="-2" count="200" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>

<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"model":{"jsonPath":"/live2dw/assets/koharu.model.json"},"display":{"position":"left","width":200,"height":400},"mobile":{"show":false},"log":false,"pluginJsPath":"lib/","pluginModelPath":"assets/","pluginRootPath":"live2dw/","tagMode":false});</script></body>
</html>
